package com.ruihu.admin.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;

import java.time.*;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class RhLocalDateTimeUtil {

    /**
     * 获取今天的起始时间
     *
     * @param localDateTime
     * @return
     */
    public static LocalDateTime beginOfToday(LocalDateTime localDateTime) {
        return LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MIN);
    }

    /**
     * 获取今天的起始时间，以Date对象返回
     *
     * @param localDateTime
     * @return
     */
    public static Date beginOfTodayToDate(LocalDateTime localDateTime) {
        return Date.from(LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MIN).atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取今天的结束时间
     *
     * @param localDateTime
     * @return
     */
    public static LocalDateTime endOfToday(LocalDateTime localDateTime) {
        return LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MAX);
    }

    /**
     * 获取今天的结束时间，以Date对象返回
     *
     * @param localDateTime
     * @return
     */
    public static Date endOfTodayToDate(LocalDateTime localDateTime) {
        return Date.from(LocalDateTime.of(localDateTime.toLocalDate(), LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取上周的周一起始时间
     *
     * @param currentDateTime
     * @return
     */
    public static LocalDateTime firstDayOfLastWeek(LocalDateTime currentDateTime) {
        LocalDateTime beginOfToday = LocalDateTime.of(currentDateTime.toLocalDate(), LocalTime.MIN);
        LocalDateTime todayOfLastWeek = beginOfToday.minusWeeks(1);
        LocalDateTime mondayOfLastWeek = todayOfLastWeek.with(TemporalAdjusters.previous(DayOfWeek.SUNDAY)).plusDays(1);
        return mondayOfLastWeek;
    }

    /**
     * 获取上周的周一起始时间，返回Date对象
     *
     * @param currentDateTime
     * @return
     */
    public static Date firstDayOfLastWeekToDate(LocalDateTime currentDateTime) {
        LocalDateTime mondayOfLastWeek = firstDayOfLastWeek(currentDateTime);
        return Date.from(mondayOfLastWeek.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取上周的周末结束时间
     *
     * @param currentDateTime
     * @return
     */
    public static LocalDateTime lastDayOfLastWeek(LocalDateTime currentDateTime) {
        LocalDateTime lastOfToday = LocalDateTime.of(currentDateTime.toLocalDate(), LocalTime.MAX);
        LocalDateTime todayOfLastWeek = lastOfToday.minusWeeks(1);
        LocalDateTime sundayOfLastWeek = todayOfLastWeek.with(TemporalAdjusters.next(DayOfWeek.MONDAY)).minusDays(1);
        return sundayOfLastWeek;
    }

    /**
     * 获取上周的周末结束时间，返回Date对象
     *
     * @param currentDateTime
     * @return
     */
    public static Date lastDayOfLastWeekToDate(LocalDateTime currentDateTime) {
        LocalDateTime sundayOfLastWeek = lastDayOfLastWeek(currentDateTime);
        return Date.from(sundayOfLastWeek.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 本周起始时间
     *
     * @param currentDateTime
     * @return
     */
    public static LocalDateTime firstDayOfThisWeek(LocalDateTime currentDateTime) {
        return LocalDateTime.of(currentDateTime.toLocalDate(), LocalTime.MIN).with(DayOfWeek.MONDAY);
    }

    /**
     * 本周起始时间返回Date对象
     *
     * @param currentDateTime
     * @return
     */
    public static Date firstDayOfThisWeekToDate(LocalDateTime currentDateTime) {
        LocalDateTime beginDayOfWeek = firstDayOfThisWeek(currentDateTime);
        return Date.from(beginDayOfWeek.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 本周结束时间
     *
     * @param currentDateTime
     * @return
     */
    public static LocalDateTime lastDayOfThisWeek(LocalDateTime currentDateTime) {
        return LocalDateTime.of(currentDateTime.toLocalDate(), LocalTime.MAX).with(DayOfWeek.SUNDAY);
    }

    /**
     * 本周结束时间，返回Date对象
     *
     * @param currentDateTime
     * @return
     */
    public static Date lastDayOfThisWeekToDate(LocalDateTime currentDateTime) {
        LocalDateTime lastDayOfWeek = lastDayOfThisWeek(currentDateTime);
        return Date.from(lastDayOfWeek.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 本月第一天
     *
     * @param currentDateTime
     * @return
     */
    public static LocalDateTime firstDayOfThisMonth(LocalDateTime currentDateTime) {
        LocalDateTime beginDayOfThisMonth = LocalDateTime.of(currentDateTime.toLocalDate(), LocalTime.MIN);
        return beginDayOfThisMonth.with(TemporalAdjusters.firstDayOfMonth());
    }

    /**
     * 本月最后一天
     *
     * @param currentDateTime
     * @return
     */
    public static LocalDateTime lastDayOfThisMonth(LocalDateTime currentDateTime) {
        LocalDateTime lastDayOfThisMonth = LocalDateTime.of(currentDateTime.toLocalDate(), LocalTime.MAX);
        return lastDayOfThisMonth.with(TemporalAdjusters.lastDayOfMonth());
    }

    /**
     * 本月第一天，返回Date
     *
     * @param currentDateTime
     * @return
     */
    public static Date firstDayOfThisMonthToDate(LocalDateTime currentDateTime) {
        LocalDateTime firstDayOfThisMonth = firstDayOfThisMonth(currentDateTime);
        return Date.from(firstDayOfThisMonth.with(TemporalAdjusters.firstDayOfMonth()).atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 本月最后一天，返回Date
     *
     * @param currentDateTime
     * @return
     */
    public static Date lastDayOfThisMonthToDate(LocalDateTime currentDateTime) {
        LocalDateTime lastDayOfThisMonth = lastDayOfThisMonth(currentDateTime);
        return Date.from(lastDayOfThisMonth.with(TemporalAdjusters.lastDayOfMonth()).atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 上月第一天
     *
     * @param currentDateTime
     * @return
     */
    public static LocalDateTime firstDayOfLastMonth(LocalDateTime currentDateTime) {
        LocalDateTime firstDayOfLastMonth = LocalDateTime.of(currentDateTime.toLocalDate(), LocalTime.MIN);
        return firstDayOfLastMonth.minusMonths(1).with(TemporalAdjusters.firstDayOfMonth());
    }

    /**
     * 上月最后一天
     *
     * @param currentDateTime
     * @return
     */
    public static LocalDateTime lastDayOfLastMonth(LocalDateTime currentDateTime) {
        LocalDateTime lastDayOfLastMonth = LocalDateTime.of(currentDateTime.toLocalDate(), LocalTime.MAX);
        return lastDayOfLastMonth.minusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
    }

    /**
     * 上月第一天，返回Date对象
     *
     * @param currentDateTime
     * @return
     */
    public static Date firstDayOfLastMonthToDate(LocalDateTime currentDateTime) {
        LocalDateTime firstDayOfLastMonth = firstDayOfLastMonth(currentDateTime);
        return Date.from(firstDayOfLastMonth.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 上月最后一天，返回Date对象
     *
     * @param currentDateTime
     * @return
     */
    public static Date lastDayOfLastMonthToDate(LocalDateTime currentDateTime) {
        LocalDateTime lastDayOfLastMonth = lastDayOfLastMonth(currentDateTime);
        return Date.from(lastDayOfLastMonth.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 本年第一天
     *
     * @param currentDateTime
     * @return
     */
    public static LocalDateTime firstDayOfThisYear(LocalDateTime currentDateTime) {
        return LocalDateTime.of(currentDateTime.toLocalDate(), LocalTime.MIN).with(TemporalAdjusters.firstDayOfYear());
    }

    /**
     * 本年最后一天
     *
     * @param currentDateTime
     * @return
     */
    public static LocalDateTime lastDayOfThisYear(LocalDateTime currentDateTime) {
        return LocalDateTime.of(currentDateTime.toLocalDate(), LocalTime.MAX).with(TemporalAdjusters.lastDayOfYear());
    }


    /**
     * 本年第一天，返回Date对象
     *
     * @param currentDateTime
     * @return
     */
    public static Date firstDayOfThisYearToDate(LocalDateTime currentDateTime) {
        LocalDateTime firstDayOfThisYear = LocalDateTime.of(currentDateTime.toLocalDate(), LocalTime.MIN).with(TemporalAdjusters.firstDayOfYear());
        return Date.from(firstDayOfThisYear.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 本年最后一天，返回Date对象
     *
     * @param currentDateTime
     * @return
     */
    public static Date lastDayOfThisYearToDate(LocalDateTime currentDateTime) {
        LocalDateTime lastDayOfThisYear = LocalDateTime.of(currentDateTime.toLocalDate(), LocalTime.MAX).with(TemporalAdjusters.lastDayOfYear());
        return Date.from(lastDayOfThisYear.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 最近七天
     * @param currentDateTime
     * @return
     */
    public static List<Date> recent7Days(LocalDateTime currentDateTime) {
        LocalDate beginSevenDaysAgo = currentDateTime.minusDays(6).toLocalDate();
        LocalDate currentDate = currentDateTime.toLocalDate();

        List<Date> recent7Days = new ArrayList<>();
        for (LocalDate day = beginSevenDaysAgo; !day.isAfter(currentDate); day = day.plusDays(1)) {
            recent7Days.add(Date.from(day.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
        }

        return recent7Days;
    }

    public static List<Date> recentOneMonthDays(LocalDateTime currentDateTime) {
        LocalDate beginSevenDaysAgo = currentDateTime.minusDays(29).toLocalDate();
        LocalDate currentDate = currentDateTime.toLocalDate();

        List<Date> recent30Days = new ArrayList<>();
        for (LocalDate day = beginSevenDaysAgo; !day.isAfter(currentDate); day = day.plusDays(1)) {
            recent30Days.add(Date.from(day.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
        }

        return recent30Days;
    }

    public static List<Date> recentOneYearDays(LocalDateTime currentDateTime) {
        LocalDate beginSevenDaysAgo = currentDateTime.minusDays(364).toLocalDate();
        LocalDate currentDate = currentDateTime.toLocalDate();

        List<Date> recentOneYearDays = new ArrayList<>();
        for (LocalDate day = beginSevenDaysAgo; !day.isAfter(currentDate); day = day.plusDays(1)) {
            recentOneYearDays.add(Date.from(day.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
        }

        return recentOneYearDays;
    }
}
